\documentclass[11pt]{article}

\usepackage[a4paper,hoffset=0.5cm,left=2cm]{geometry}

% Vamos a escribir en castellano:
\usepackage[utf8]{inputenc}
\usepackage[spanish]{babel}
\usepackage{amsmath}
\usepackage{amsthm}
\usepackage{amssymb}
\usepackage{verbatim}
\usepackage{courier}
\usepackage{tikz}
%\usepackage{mathaccent}
\usepackage{listings}
\usepackage{color}
%\usepackage{sans}
\usepackage{wrapfig}
\usepackage{multicol}
\usepackage{tipa}

\lstset{
	language=C++,
	basicstyle=\footnotesize\ttfamily,	% print whole listing small
	keywordstyle=\bfseries,
%	numbers=left,
%	numberstyle=\footnotesize,
%	frame=single,
	breaklines=true,
	identifierstyle=,			% nothing happens
	stringstyle=\ttfamily,		% typewriter type for strings
	showstringspaces=false		% no special string spaces
}						

\title{75.74 - Sistemas Distribuidos \\ Prácticas de Laboratorio}
\author{Esteban Alejandro Czelada}
\renewcommand{\thesubsubsection}{\Alph{subsubsection}}

\begin{document}

\begin{titlepage}
	\maketitle
	\thispagestyle{empty}
	\begin{abstract}
		El presente informe contiene las descripciones de los ejercicios correspondientes a la práctica de laboratorio de la materia 75.74 - Sistemas Distribuidos de la Facultad de Ingeniería de la Universidad de Buenos Aires correspondiente al curso del segundo cuatrimestre del año 2011.
	\end{abstract}
\end{titlepage}

\section{Generalidades}
Todos los ejercicios presentan la misma estructura básica y utilizan las mismas facilidades provistas por las carpetas \emph{utils} e \emph{ipc}, cada una correspondiente al \emph{namespace} homónimo.

\subsection{Estructura de archivos de cada ejercicio}
\begin{itemize}
	\item Existe un archivo \emph{common.hpp}, el cual define las constantes globales e incluye los encabezados comunes a todos los ejecutables.
	\item El proceso de compilación define la variable \emph{BASE\_NAME} utilizada como base para las llamadas a \emph{ftok}.
	\item Cada archivo \emph{.cpp} constituye un ejecutable.
	\item Todo objeto que era más entendible separado del ejecutable se a definido en un \emph{.hpp}, otros han quedado embebidos en el código del ejecutable.
	\item Un copia del archivo \emph{Makefile}. En la siguiente sección se explican los objetivos útiles para la compilación y ejecución.
	\item Una copia del directorio \emph{utils}.
	\item Una copia del directorio \emph{ipc}.
\end{itemize}

\subsection{Compilación de cada ejercicio}
El archivo \emph{Makefile} define dos formas de construir la resolución.

\begin{itemize}
	\item ``\emph{make}'': El objetivo por defecto construye el ejercicio en el mismo directorio, utilizando el mismo como valor de la variable \emph{BASE\_NAME}.
	\item ``\emph{make deploy}'': Compila el ejercicio y copia los ejecutables al directorio de trabajo correspondiente. Se asigna el nombre del directorio de implantación a la variable \emph{BASE\_NAME}.
	\item Se provee un objetivo \emph{clean} para limpiar el directorio de compilación, y \emph{undeploy} para eliminar los archivos generados por \emph{deploy}.
\end{itemize}

\subsection{Ejecución de cada ejercicio}
Todos los ejecutables utilizan \emph{getopt} para el procesamiento de parámetros, y definen el parámetro \emph{-h} (\emph{--help}) para mostrar un breve mensaje de ayuda por pantalla.

En el directorio \emph{utils} se proveen \emph{scripts} utilitarios para destruir procesos y objetos IPC remanentes.

Todos los ejercicios definen dos ejecutables \emph{lanzador} y \emph{destructor}, el primero encargado de crear e inicializar todos los objetos IPC y lanzar los procesos que resuelven el ejercicio particular, en cambio el segundo está encargado de destruir los mismos objetos.

Todos los objetos IPC se crean con los permisos definidos en \emph{common.hpp}

\textbf{Para todo ejercicio se crean los identificadores de objetos IPC utilizando una llamada similar a \emph{ftok(BASE\_NAME,discriminante)}. Donde \emph{BASE\_NAME} es el nombre del directorio del ejercicio, y discriminante es un valor único asignado a cada objeto (con la salvedad de algunos semáforos y memorias compartidas que usan el mismo discriminante ya que su tipo los diferencia). En los cuadros solo se indicara el discriminante empleado en cada objeto IPC, y el nombre global asignado.}

En los cuadros donde se detallan los objetos IPC se ha optado por la siguiente notación:
\begin{itemize}
	\item \emph{sem(i)} corresponde al semáforo en la posición correspondiente de un vector.
	\item \emph{vsem[N]} corresponde a un vector de N semáforos. (Todos los semáforos son vectores, pero por lo general son de un solo elemento).
	\item \emph{shm$<$T$>$} corresponde a una memoria compartida especializada para el tipo \emph{T}.
	\item \emph{mq} corresponde a una cola de mensajes.
\end{itemize}

El proceso \emph{lanzador} espera que ninguno de los objetos a crear exista. En caso de no poder crear alguno no se lanzan los demás procesos, y el lanzador aborta con una excepción, que es atrapada e informada.

El proceso \emph{destructor} fuerza la destrucción de todo objeto IPC que pueda. Debido a que en los demás procesos se utilizan las versiones de los objetos IPC que informan el fallo mediante excepciones, que son atrapadas e informadas.

El registro de las actividades se realiza mediante el uso de la clase \emph{utils::logger\_stream} la cual encapsula una llamada a \emph{fwrite} y una instancia de \emph{std::stringstream} con el fin de proveer las facilidades del operador $\ll$ y la atomicidad de \emph{fwrite}, además de proveer una forma de pintar la salida de colores (en linux).

Cada proceso particular sigue la misma estructura general:
\begin{enumerate}
	\item Definir objetos IPC. (Algunos objetos IPC se crean luego de la lectura de los parámetros cuando es conveniente).
	\item Interpretar argumentos (si hay error informa con mensaje de ayuda).
	\item Inicializar \emph{utils::logger\_stream}.
	\item Realizar la llamada al método \emph{get} de cada objeto IPC.
	\item Comenzar bucle principal.
	\item Realizar su tarea hasta abortar por excepción.
	\item Atrapar excepciones definidas en \emph{ipc/exception.hpp}.
\end{enumerate}

\newpage
\section{Detalles particulares de cada ejercicio}
\subsection{Ejercicio 1.1}
El ejercicio corresponde a la exclusión mutua en el acceso a recursos compartidos (la cantidad de personas dentro del gimnasio). Las alternativas son utilizar una memoria compartida para almacenar el dato compartido y un semáforo para permitir la exclusión mutua en el acceso al mismo o que el dato sea adquirido de una cola donde se utilice un token para representar los datos compartidos, yo opte por la primera opción. 

\subsubsection{Procesos}
\begin{itemize}
	\item \emph{puerta}: Encargado de generar ingresos y egresos de personas al gimnasio cada cierto tiempo.
\end{itemize}

\subsubsection{Mensajes y memorias compartidas}
Para este ejercicio solo es necesario actualizar la cantidad de personas existentes en el gimnasio, esa función la cumple el campo \emph{cantidad} de la estructura \emph{sGimnasio} que se almacena en una memoria compartida.

\begin{lstlisting}
	typedef struct {
		size_t cantidad;
	} sGimnasio;
\end{lstlisting}

\subsubsection{Objetos IPC}
Los procesos no se comunican más allá de actualizar la cantidad de personas en el gimnasio. A fin de sincronizar el acceso a la memoria compartida se utiliza un semáforo.

\begin{table}[ht!]
\centering
\begin{tabular}{l|l|c}
	\emph{Nombre} & \emph{Tipo} & \emph{Disc.} \\
	\hline
	mutex	& sem(0)	& 10 \\
	gim		& shm$<$sGimnasio$>$ & 11 \\
\end{tabular}
\caption{Objetos IPC del ejercicio 1.1}
\end{table}

\newpage
\subsection{Ejercicio 1.2}
Este ejercicio solo agrega la necesidad de controlar que la cantidad de personas no supere un máximo dado. Se ha optado por agregar un campo más a la memoria compartida \emph{máximo}. El resto del ejercicio es igual, salvo cuando un cliente desea entrar y están ocupados todos los lugares. Además se muestra en el archivo \emph{puerta\_2.cpp} como se resolvería el ejercicio utilizando el objeto \emph{ipc::bounded\_counter} que encapsula un semáforo y una memoria compartida que puede valor entre 0 y un máximo (luego se utliza en otros ejercicios y este es una buena presentación).

\subsubsection{Procesos}
\begin{itemize}
	\item \emph{puerta}: Encargado de generar ingresos y egresos de personas al gimnasio cada cierto tiempo.
	\item \emph{puerta\_2}: Idem \emph{puerta} pero utilizando \emph{ipc::bounded\_counter}.
\end{itemize}

\subsubsection{Mensajes y memorias compartidas}
La memoria compartida se define como:

\begin{multicols}{2}
Definido en \emph{common.hpp}
\begin{lstlisting}
	typedef struct {
		size_t cantidad;
		size_t maximo;
	} sGimnasio;
\end{lstlisting}


Definido en \emph{ipc/bounded\_counter.hpp}
\begin{lstlisting}
	typedef struct {
		size_t actual;
		size_t max;
	} sBoundedValue;
\end{lstlisting}

\end{multicols}

\subsubsection{Objetos IPC}
Los procesos no se comunican más allá de actualizar la cantidad de personas en el gimnasio. A fin de sincronizar el acceso a la memoria compartida se utiliza un semáforo.

Se utiliza el ejercicio para presentar como se muestran las claves utilizadas al mostrar una instancia de \emph{ipc::bounded\_counter}.

\begin{table}[ht!]
\centering
\begin{tabular}{l|l|c}
	\emph{Nombre} & \emph{Tipo} & \emph{Disc.} \\
	\hline
	mutex	& sem(0)	& 10 \\ 
	gim		& shm$<$sGimnasio$>$ & 11 \\
	\hline
	gim.mutex & sem(0)	& 10 \\ 
	gim.value	& shm$<$sBoundedValue$>$ & 11 \\	
\end{tabular}
\caption{Objetos IPC del ejercicio 1.2}
\end{table}

\newpage
\subsection{Ejercicio 1.3}
En este ejercicio se agrega la necesidad de representar las personas como procesos y estos deben poder comunicarse con la entrada y salida al gimnasio, lo que genera una sección crítica compartida entre varios procesos (el hecho de que un proceso este ocupando un lugar dentro del gimnasio), o tambien puede ser vista como la utilización de un recurso compartido que tiene un cupo. 

\subsubsection{Procesos}
\begin{itemize}
	\item \emph{arribos}: Se encarga generar una cierta cantidad de personas en intervalos variables.
	\item \emph{persona}: Una persona que desea entrar al gimnasio. Primero intentar entrar, de tener exito se queda cierto tiempo ocupando un lugar y luego finalmente sale. En el momento de la creación se selecciona al azar que puerta se usara para entrar y salir.
	\item \emph{puerta}: Crea una cola de mensajes a partir de una clave (IPC) para recibir y procesar los mensajes \emph{E} y \emph{S}. Ambos mensajes se responden con un eco, salvo el mensaje \emph{E} que en caso de que el gimnasio este lleno se responde con \emph{S}. Los procesos puerta son los unicos que modifican el valor de la cantidad de personas en el gimnasio.
\end{itemize}

\subsubsection{Mensajes y memorias compartidas}
Se utliliza el mismo esquema que el ejercicio anterior para el manejo de la cantidad de personas (es decir un semáforo y una memoria compartida), pero se agrega una cola de mensajes para la comunicación entre cada persona y la puerta (que es el proceso encargado de denegar el acceso en caso de que el gimnasio este lleno).

Cada \emph{puerta} atiende una cola que sirve de canal de comunicación entre la misma y todos las \emph{personas} que desean entrar y/o salir del gimnasio.

\begin{multicols}{2}
\begin{lstlisting}
	typedef struct {
		size_t cantidad;
		size_t maximo;
	} sGimnasio;
\end{lstlisting}

\begin{lstlisting}

	typedef struct {
		long tipo;
		long origen;
		char data;
	} sMensaje;
\end{lstlisting}

\end{multicols}

El campo tipo es el campo necesario por las colas de mensajes IPC, se utiliza el campo tipo para indicar el destino del mensaje, con la notación de que el destino \emph{1} es el dueño de la cola de mensajes, el campo origen se llena con el identificador del proceso que envia el mensaje (para responder se utiliza ese identificador para ubicar un mensaje en la cola). La cola se utiliza como un canal half-duplex donde cada proceso es responsable de sacar de la misma solo los mensajes que le corresponden. \emph{Este esquema de del identificador 1 para el dueño de la cola, y el identificador del proceso para los demás se utiliza los siguientes ejercicios}.

El significado del mensaje se atribuye según el contendio del campo data:
\begin{itemize}
	\item \emph{E} puede ser un mensaje de un cliente a una puerta pidiendo entrar, o un mensaje de la puerta a un cliente confirmando que puede entrar.
	\item \emph{S} puede ser un mensaje de un cliente a una puerta pidiendo salir, o un mensaje de la puerta a un cliente confirmando que puede salir, o tambien la orden de retirarse por que el gimnasio esta lleno.
\end{itemize}

\subsubsection{Objetos IPC}
Al ejercicio anterior se agrega la comunicación de las personas con las puertas a fin de realizar el control de la entrada de personas al gimnasio.

El proceso \emph{persona} llama a las colas de mensajes \emph{colaE} y \emph{colaS}, ya que pueden ser la misma.

Para simplificar el código se ha optado por aplicar la exclusión mutua en la atención de cada mensaje. Es decir en todo instante solo hay una puerta atendiendo un mensaje. Para reparar este error, se debe portar el código a utiliar \emph{ipc::bounded\_counter} que es en escencia un monitor.

Las correspondientes colas sirven como medio de serialización de cada puerta, ya que solo debe existir una puerta por instancia de una cola de mensajes. Se pueden agregar más puertas al gimnasio modificando, \emph{lanzador.cpp}, \emph{destructor.cpp} para crear y liberar los recursos necesarios correctamente, a su vez se debe modificar la constante que utilizan las personas para seleccionar que puerta utilizar.

\begin{table}[ht!]
\centering
\begin{tabular}{l|l|c}
	\emph{Nombre} & \emph{Tipo} & \emph{Disc.} \\
	\hline
	mutex	& sem(0)	& 10 \\ 
	gim		& shm$<$sGimnasio$>$ & 11 \\
	cola1	& mq		& 16 \\
	cola2	& mq		& 17 \\
\end{tabular}
\caption{Objetos IPC del ejercicio 1.3}
\end{table}

\newpage
\subsection{Ejercicio 2.1}
El problema es un ejemplo de consumidores productores, donde cada estación utiliza los productos de la anterior para generar un producto nuevo. Además existe la utilización de recursos compartidos entre las diferentes estaciones de igual tipo.

\subsection{Ejercicio 2.2}
Para resolverlo con memoria compartida se ha optado por usar una memoria compartida y un semáforo por cada recurso (botellas vacias, botellas llenas, botellas etiquetadas, botellas listas), como cada estación tiene una cantidad del otro recurso cada uno funciona hasta agotarlo (por ejemplo las tapadores siguen tapando hasta agotarse las tapas o no poder obtener más botellas.

Se forzado el orden de las estaciones a: $llenadora \rightarrow tapadora \rightarrow etiquetadora$.

\subsubsection{Procesos}
\begin{itemize}
	\item \emph{llenadora}: Toma botellas vacias (decrementando la variable compartida \emph{vacias}), las llenas (si tiene dosis de jugo) y las deposita en la cinta transportadora a la siguiente estación (incrementa \emph{llenas}).
	\item \emph{tapadora}: Toma botellas llenas (decrementando la variable compartida \emph{llenas}), las tapa (si tiene tapas) y las deposita en la cinta transportadora a la siguiente estación (incrementa \emph{tapadas}).
	\item \emph{etiquetadora}: Toma botellas tapadas (decrementando la variable compartida \emph{tapadas}), las etiqueta (si tiene etiquetas) y las deposita en la cinta transportadora al deposito (incrementa \emph{listas}).
	\item \emph{stock}: Proceso de utilidad para mostrar los valores de cada variable compartida en un instante.
\end{itemize}

\subsubsection{Mensajes y memorias compartidas}
Todas las memorias compartidas son un \emph{size\_t} y se utilizan para almacenar la cantidad de botellas en el estado correspondiente al nombre que tienen.

\subsubsection{Objetos IPC}
Todas las estaciones tienen la misma estructura general:
\begin{enumerate}
	\item Tomar recurso local (Si falta informar y detener la ejecución). Por ejemplo dosis de jugo en la llenadora.
	\item Tomar botella sin procesar (Si falta detenerse a la espera que otra estación informe que hay recursos). Por ejemplo botellas vacias en la llenadora.
	\item Procesar botella: aplicar recurso local a la botella. 
	\item Liberar botella a la siguiente estación.
\end{enumerate}

En la siguiente tabla se muestran las constantes utilizadas para la generación de las claves, que se corresponden con la siguiente definicion:
\begin{lstlisting}
	enum botellas { VACIAS = 1, LLENAS, TAPADAS, ETIQUETADAS, LISTAS };
	enum maquinas { LLENADORA = 8, TAPADORA, ETIQUETADORA };

	#define MUTEX 64
	#define COUNTER 128
	#define MAX_LLENADORAS 5 
\end{lstlisting}

Para permitir un número variable de llenadoras, se ha elejido utilizar un vector de semáforos con una cantidad maxima definida. No se comprobo que sucede si se trata de crear más llenadoras que el máximo (debería fallar con una excepción en el semáforo \emph{mutex\_llenadoras}), o si se lanzan dos llenadoras con los mismos identificadores.

\begin{table}[ht!]
\centering
\begin{tabular}{l|l|l@{=}r}
	\emph{Nombre} & \emph{Tipo} & \emph{Discriminante} & \emph{Val.} \\
	\hline
	vacias	& shm$<$size\_t$>$	& COUNTER\textpipe VACIAS & 129 \\
	llenas	& shm$<$size\_t$>$	& COUNTER\textpipe LLENAS & 130 \\
	tapadas	& shm$<$size\_t$>$	& COUNTER\textpipe TAPADAS & 131 \\
	listas	& shm$<$size\_t$>$	& COUNTER\textpipe LISTAS & 133 \\

	mutex\_vacias	& sem(0)	& MUTEX\textpipe VACIAS & 65 \\
	mutex\_llenas	& sem(0)	& MUTEX\textpipe LLENAS & 66 \\
	mutex\_tapadas	& sem(0)	& MUTEX\textpipe TAPADAS	& 67 \\ 
	mutex\_listas	& sem(0)	& MUTEX\textpipe LISTAS & 69 \\

	mutex\_llenadoras & vsem[MAX\_LLENADORAS = 5]	& MUTEX\textpipe LLENADORA & 72 \\
	mutex\_tapada	& sem(0)	& MUTEX\textpipe TAPADORA & 73 \\ 	
	mutex\_etiquetadora & sem(0)	& MUTEX\textpipe ETIQUETADORA & 74 \\ 
\end{tabular}
\caption{Objetos IPC del ejercicio 2.2}
\end{table}

\newpage
\subsection{Ejercicio 2.3}
El mayor cambio con respecto a la solución que utiliza memoria compartida es la creación de un mensaje que representa una botella y su estado, y la union de las estaciones mediante colas de mensajes en las que cada estación deposita su producto terminado y toma el recurso botella correspondiente.

Se forzado el orden de las estaciones a: $llenadora \rightarrow tapadora \rightarrow etiquetadora$.

\subsubsection{Procesos}
\begin{itemize}
	\item \emph{llenadora}: Toma botellas vacias (decrementando la variable compartida \emph{vacias}), las llenas (si tiene dosis de jugo) y las deposita en la cinta transportadora a la siguiente estación (generando un mensaje y poniendolo en la cola correspondiente).
	\item \emph{tapadora}: Toma botellas llenas (tomando un mensaje de la cola correspondiente), las tapa (si tiene tapas) y las deposita en la cinta transportadora a la siguiente estación (generando un mensaje y poniendolo en la cola correspondiente).
	\item \emph{etiquetadora}: Toma botellas tapadas  (tomando un mensaje de la cola correspondiente), las etiqueta (si tiene etiquetas) y las deposita en la cinta transportadora al deposito (incrementa \emph{listas}).
	\item \emph{stock}: Proceso de utilidad para mostrar los valores de cada variable compartida en un instante. En este caso solo se lleva registro de las botellas vacias y las llenas.
\end{itemize}

\subsubsection{Mensajes y memorias compartidas}
Todas las memorias compartidas son un \emph{size\_t} y se utilizan para almacenar la cantidad de botellas en el estado correspondiente al nombre que tienen.

Todos los mensajes son del unico tipo \emph{SBOTELLA\_TIPO}, y se diferencian por el valor del campo estado que indica que estaciones han procesado la botella.

\begin{lstlisting}
enum eEstado { VACIA, LLENA, TAPADA, ETIQUETADA, COMPLETA };

typedef struct {
	long tipo;
	eEstado estado;
} sBotella;

enum eMensajeTipo { CUALQUIERA = 0, SBOTELLA_TIPO };
\end{lstlisting}

\subsubsection{Objetos IPC}
En la siguiente tabla se muestran las constantes utilizadas para la generación de las claves, que se corresponden con la siguiente definicion:
\begin{lstlisting}
	enum botellas { VACIAS = 1, LLENAS, TAPADAS, ETIQUETADAS, LISTAS };
	enum maquinas { LLENADORA = 8, TAPADORA, ETIQUETADORA };

	#define MUTEX 64
	#define COUNTER 128
	#define MSG_QUEUE 192
	#define MAX_LLENADORAS 5 
\end{lstlisting}

Para permitir un número variable de llenadoras, se ha elejido utilizar un vector de semáforos con una cantidad maxima definida. No se comprobo que sucede si se trata de crear más llenadoras que el máximo (debería fallar con una excepción en el semáforo \emph{mutex\_llenadoras}), o si se lanzan dos llenadoras con los mismos identificadores.

\begin{table}[ht!]
\centering
\begin{tabular}{l|l|l@{=}r}
	\emph{Nombre} & \emph{Tipo} & \emph{Discriminante} & \emph{Val.} \\
	\hline
	vacias	& shm$<$size\_t$>$	& COUNTER\textpipe VACIAS & 129 \\
	listas	& shm$<$size\_t$>$	& COUNTER\textpipe LISTAS & 133 \\

	mutex\_vacias	& sem(0)	& MUTEX\textpipe VACIAS & 65 \\
	mutex\_listas	& sem(0)	& MUTEX\textpipe LISTAS & 69 \\

	mutex\_llenadoras & vsem[MAX\_LLENADORAS = 5]	& MUTEX\textpipe LLENADORA & 72 \\
	mutex\_tapada	& sem(0)	& MUTEX\textpipe TAPADORA & 73 \\
	mutex\_etiquetadora & sem(0)	& MUTEX\textpipe ETIQUETADORA & 74 \\

	llenadoras\_salida & mq	& MSG\_QUEUE\textpipe LLENADORA & 200 \\
	tapadora\_salida & mq	& MSG\_QUEUE\textpipe TAPADORA & 201 \\
\end{tabular}
\caption{Objetos IPC del ejercicio 2.3}
\end{table}

\newpage
\subsection{Ejercicio 2.4}
Al agregar la cinta transportadora que alimenta las llenadoras, los procesos que representan cada llenadora pasan a tomar las botellas de la cola correspondiente a la salida de la transportadora (representada por \emph{transportadora\_A}).

Además se agregan a la solución tipos de recursos, para poder pedir con exactitud que recurso a cada transportadora.

\subsubsection{Procesos}
\begin{itemize}
	\item \emph{transportadora\_A}: Toma botellas vacias del almacen y las entrega a la boca libre correspondiente.
	\item \emph{llenadora}: Toma botellas vacias (tomando un mensaje de la cola de correspondiente), las llenas (si tiene dosis de jugo) y las deposita en la cinta transportadora a la siguiente estación (generando un mensaje y poniendolo en la cola correspondiente).
	\item \emph{tapadora}: Toma botellas llenas (tomando un mensaje de la cola correspondiente), las tapa (si tiene tapas) y las deposita en la cinta transportadora a la siguiente estación (generando un mensaje y poniendolo en la cola correspondiente).
	\item \emph{etiquetadora}: Toma botellas tapadas  (tomando un mensaje de la cola correspondiente), las etiqueta (si tiene etiquetas) y las deposita en la cinta transportadora al deposito (incrementa \emph{listas}).
\end{itemize}

\subsubsection{Mensajes y memorias compartidas}
Todas las memorias compartidas son un \emph{size\_t} y se utilizan para almacenar la cantidad de botellas en el estado correspondiente al nombre que tienen.

La estación de llenado utiliza mensajes del tipo \emph{sPedido} indicandolo con el campo tipo en \emph{SRECURSO\_TIPO} indicando que solicita una botella, y espera recibir un mensaje de respuesta del tipo \emph{sBotella} en estado vacio. A fin de que el proceso encargado de enviar las botellas vacias pueda diferenciar cada transportadora, Se identifican a partir del valor de \emph{SESTACION\_0}.

Por su parte la transportadora espera mensajes del tipo \emph{SRECURSO\_TIPO} y luego de interpretar sus intenta responder.

En caso de agotarse las botellas la llenadora queda bloqueada esperando recibir una botella.

Todos los mensajes son del unico tipo \emph{SBOTELLA\_TIPO}, y se diferencian por el valor del campo estado que indica que estaciones han procesado la botella.

\begin{lstlisting}
	enum eEstado { VACIA, LLENA, TAPADA, ETIQUETADA, COMPLETA };

	typedef struct {
		long tipo;
		eEstado estado;
	} sBotella;

	// Representacion del pedido de un recurso dado.
	enum eRecurso { NINGUNO, BOTELLA, JUGO, TAPA, ETIQUETA };
	typedef struct {
		long tipo;
		long estacion;
		eRecurso recurso;
	} sPedido;

	// Discriminantes para los tipos de mensajes utilizados en las colas.
	enum eMensajeTipo { CUALQUIERA = 0, SBOTELLA_TIPO, SRECURSO_TIPO, SESTACION_0 = 128 };
\end{lstlisting}

\subsubsection{Objetos IPC}
En la siguiente tabla se muestran las constantes utilizadas para la generación de las claves, que se corresponden con la siguiente definicion:

\begin{lstlisting}
	// Para simplificar la creacion de objetos IPC.
	enum botellas { VACIAS = 1, LLENAS, TAPADAS, ETIQUETADAS, LISTAS };
	enum maquinas { LLENADORA = 8, TAPADORA, ETIQUETADORA, TRANSPORTADORA_A };

	// Marca de que corresponde a un semaforo mutex.
	#define MUTEX 64
	// Marca de que corresponde a una variable compartida utilizada como contador.
	#define COUNTER 128
	// Marca de que corresponde a una cola de mensajes.
	#define MSG_QUEUE 192
\end{lstlisting}

\begin{table}[ht!]
\centering
\begin{tabular}{l|l|l@{=}r}
	\emph{Nombre} & \emph{Tipo} & \emph{Discriminante} & \emph{Val.} \\
	\hline
	listas	& shm$<$size\_t$>$	& COUNTER\textpipe LISTAS & 133 \\
	mutex\_listas	& sem(0)	& MUTEX\textpipe LISTAS & 69 \\

	mutex\_llenadoras & vsem[\scriptsize{MAX\_LLENADORAS = 5}]	& MUTEX\textpipe LLENADORA & 72 \\
	mutex\_tapada	& sem(0)	& MUTEX\textpipe TAPADORA & 73 \\
	mutex\_etiquetadora & sem(0)	& MUTEX\textpipe ETIQUETADORA & 74 \\
	mutex\_transportadoraA & sem(0)	& MUTEX\textpipe TRANSPORTADORA\_A & 75 \\
	
	llenadoras\_salida & mq	& MSG\_QUEUE\textpipe LLENADORA & 200 \\
	tapadora\_salida & mq	& MSG\_QUEUE\textpipe TAPADORA & 201 \\
	transportadoraA\_salida & mq	& MSG\_QUEUE\textpipe TRANSPORTADORA\_A & 203 \\
\end{tabular}
\caption{Objetos IPC del ejercicio 2.4}
\end{table}

\newpage
\subsection{Ejercicio 2.5}
El agregado del proceso repositor hace necesario el uso de colas de mensajes para comunicar los pedidos de aprovicionamiento de cada estación al repositor, lo que lleva a extender el mecanismo utilizado en el ejercicio anterior para la \emph{transportadoraA}.

El mensaje de pedido de recursos se vuelve más complejo, para permitir a las estacioones bloquearse en un semáforo a la espera que el repositor informe el aprovisionamiento cuando sea posible. Debido a que las llenadoras utilizan un vector de semáforos es necesario enviar tanto la clave del vector como el indice.

\subsubsection{Procesos}
\begin{itemize}
	\item \emph{transportadora\_A}, \emph{llenadora}, \emph{tapadora}, \emph{etiquetadora}: Todos siguen la misma estructura intentan obtener el recurso \emph{local} (las tapas en la tapadora), si no tiene envia un mensaje al repositor solicitandolo y se queda esperando en un semáforo a que el repositor lo despierte, luego solicitan una botella a la transportadora de entrada a la estación, si aun no hay botellas la estación queda detenida a la espera de que le proveean de botellas.
	\item \emph{repositor}: El repositor tiene una cantidad de cada recurso disponible, cada vez que una estación solicita recursos, este toma un pack y se lo envia.
\end{itemize}

\subsubsection{Mensajes y memorias compartidas}
Los cambios notables en los mensajes que viajan representando botellas o pedidos de recursos son:
\begin{itemize}
	\item a \emph{sBotella} se le agrega un identificador para poder observar por pantalla que botella pasa por las estaciones.
	\item a \emph{sPedido} se agrega \emph{sem\_key}, y \emph{sem\_num} que le permiten al repositor y a la transportadoraA construir un semáforo para poder señalizar la entrega de recursos y permitir a la estación continuar su tarea.
	\item se agrega \emph{sReposicion} que principalmente representa la entrega de un recurso dado a una estación. 
\end{itemize}

\begin{lstlisting}
	// Usado como identificador de mensaje de entrada.
	#define PEDIR_RECURSO 1

	enum eEstado { VACIA, LLENA, TAPADA, ETIQUETADA, COMPLETA };

	typedef struct {
		long tipo;
		eEstado estado;
		size_t id;
	} sBotella;

	// Representacion del pedido de un recurso dado.
	enum eRecurso { NINGUNO, BOTELLA, JUGO, TAPA, ETIQUETA };
	typedef struct {
		long tipo;
		pid_t origen;
		eRecurso recurso;
		key_t sem_key;
		size_t sem_num;
	} sPedido;

	typedef struct {
		long tipo;
		eRecurso recurso;
		size_t cantidad;
	} sReposicion;

	// Discriminantes para los tipos de mensajes utilizados en las colas.
	enum eMensajeTipo { CUALQUIERA = 0, SBOTELLA_TIPO, SRECURSO_TIPO, SESTACION_0 = 128 };
\end{lstlisting}

\subsubsection{Objetos IPC}
En la siguiente tabla se muestran las constantes utilizadas para la generación de las claves, que se corresponden con la siguiente definicion:

\begin{lstlisting}
	// Para simplificar la creacion de objetos IPC.
	enum eBotellas { VACIAS = 1, LLENAS, TAPADAS, ETIQUETADAS, LISTAS };

	enum eMaquinas { TAPADORA = 8, ETIQUETADORA, TRANSPORTADORA_A, REPOSITOR, LLENADORA_0 = 128 };
	// LLENADORA_0 se utiliza para el semaforo y para identificar la boca 0.
	// LLENADORA_0+i se utiliza para identificar las bocas.

	// Marca de que corresponde a un semaforo mutex.
	#define MUTEX 64
	// Marca de que corresponde a una variable compartida utilizada como contador.
	#define COUNTER 128
	// Marca de que corresponde a una cola de mensajes.
	#define MSG_QUEUE 192
\end{lstlisting}

\begin{table}[ht!]
\centering
\begin{tabular}{l|l|l@{=}r}
	\emph{Nombre} & \emph{Tipo} & \emph{Discriminante} & \emph{Val.} \\
	\hline
	listas	& shm$<$size\_t$>$	& COUNTER\textpipe LISTAS & 133 \\
	mutex\_listas	& sem(0)	& MUTEX\textpipe LISTAS & 69 \\

	mutex\_llenadoras & vsem[\scriptsize{MAX\_LLENADORAS = 5}]	& MUTEX\textpipe LLENADORA\_0 & 72 \\
	mutex\_tapada	& sem(0)	& MUTEX\textpipe TAPADORA & 73 \\
	mutex\_etiquetadora & sem(0)	& MUTEX\textpipe ETIQUETADORA & 74 \\
	mutex\_transportadoraA & sem(0)	& MUTEX\textpipe TRANSPORTADORA\_A & 75 \\
	mutex\_repositor & sem(0)	& MUTEX\textpipe REPOSITOR & 76 \\
	
	llenadoras\_salida & mq	& MSG\_QUEUE\textpipe LLENADORA\_0 & 200 \\
	tapadora\_salida & mq	& MSG\_QUEUE\textpipe TAPADORA & 201 \\
	etiquetadora\_salida & mq 	& MSG\_QUEUE\textpipe ETIQUETADORA & 202 \\
	transportadoraA\_salida & mq	& MSG\_QUEUE\textpipe TRANSPORTADORA\_A & 203 \\
	repositor\_salida & mq	& MSG\_QUEUE\textpipe REPOSITOR & 204 \\
\end{tabular}
\caption{Objetos IPC del ejercicio 2.5}
\end{table}

\newpage
\subsection{Ejercicio 3.1.a}
El unico cambio aplciado a este ejercicio es la utilización de un proceso por cada llenadora, denominado\emph{azucaradora}, encargado de proveer de dosis de azucar a la llenadora en el momento que esta la necesita.

El inciso de resolver usando memoria compartido se ha entendido como \emph{resolver la sincronización entre la llenadora y la azucaradora usando memoria compartida}, a tal fin cada \emph{llenadora} coloca su variable de sincronización en \emph{2}, avisa a la \emph{azucaradora} que se prepare y una vez que esta lista para llenar decrementa el contador y espera sobre un semáforo, la \emph{azucaradora} realiza una tarea similar y tambien decrementa el contador. Finalmente el ultimo proceso (la \emph{azucaradora} o la \emph{llenadora}) en decrementar el contador activa al otro proceso y ambos actuan en simultaneo sobre la botella.

\subsubsection{Procesos}
\begin{itemize}
	\item \emph{transportadora\_A}, \emph{tapadora}, \emph{etiquetadora}, \emph{repositor}: Siguen funcionando igual que antes.
	\item \emph{llenadora}: Ahora el proceso de llenado requiere la actuación sincronizada con una azucaradora. 
	\item \emph{azucaradora}: Al igual que las demás estaciones tiene una cantidad de recursos locales disponibles (dosis de azucar), y espera la señalización de que existe botella para llenar por parte de la llenadora para actuar.
\end{itemize}

\subsubsection{Mensajes y memorias compartidas}
El sistema de mensajes sigue siendo igual que antes con la salvedad que se agregan los tipos de recursos \emph{AZUCAR} y \emph{JUGO\_SIN\_AZUCAR}. Principalmente utilizado en los siguientes incisos.
\begin{lstlisting}
	enum eRecurso { NINGUNO, BOTELLA, JUGO, TAPA, ETIQUETA, AZUCAR, JUGO_SIN_AZUCAR };
\end{lstlisting}

\subsubsection{Objetos IPC}
En la siguiente tabla se muestran las constantes utilizadas para la generación de las claves, que se corresponden con la siguiente definicion:
\begin{lstlisting}
	MAX_LLENADORAS 5

	// Para simplificar la creacion de objetos IPC.
	enum eBotellas { VACIAS = 1, LLENAS, TAPADAS, ETIQUETADAS, LISTAS };

	enum eMaquinas { TAPADORA = 8, ETIQUETADORA, TRANSPORTADORA_A, REPOSITOR, AZUCARADORA_0, LLENADORA_0 = 32};

	// Selecciono un discriminante para los mecanismos de sincronizacion entre las azucradoras y las llenadoras.
	#define SYNC (LISTAS+1)

	// LLENADORA_0 se utiliza para el semaforo y para identificar la boca 0.
	// LLENADORA_0+i se utiliza para identificar las bocas.
	// AZUCARADORA_0 idem LLENADORA_0 pero para las bocas que aportar azucar.

	// Marca de que corresponde a un semaforo mutex.
	#define MUTEX 64
	// Marca de que corresponde a una variable compartida utilizada como contador.
	#define COUNTER 128
	// Marca de que corresponde a una cola de mensajes.
	#define MSG_QUEUE 192

	// Usado como identificador de mensaje de entrada.
	#define PEDIR_RECURSO 1
\end{lstlisting}
\begin{table}[ht!]
\centering
\begin{tabular}{l|l|l@{=}r}
	\emph{Nombre} & \emph{Tipo} & \emph{Discriminante} & \emph{Val.} \\
	\hline
	listas	& shm$<$size\_t$>$	& COUNTER\textpipe LISTAS & 133 \\
	mutex\_listas	& sem(0)	& MUTEX\textpipe LISTAS & 69 \\
	sync 	& shm$<$size\_t$>$	& COUNTER\textpipe SYNC & 134 \\
	mutex\_sync	& sem(0)	& MUTEX\textpipe SYNC & 70 \\

	mutex\_llenadoras & vsem[\scriptsize{MAX\_LLENADORAS = 5}]	& MUTEX\textpipe LLENADORA\_0 & 96 \\
	mutex\_tapada	& sem(0)	& MUTEX\textpipe TAPADORA & 72 \\
	mutex\_etiquetadora & sem(0)	& MUTEX\textpipe ETIQUETADORA & 73 \\
	mutex\_transportadoraA & sem(0)	& MUTEX\textpipe TRANSPORTADORA\_A & 74 \\
	mutex\_repositor & sem(0)	& MUTEX\textpipe REPOSITOR & 75 \\
	mutex\_azucaradoras	& vsem[\scriptsize{MAX\_LLENADORAS = 5} & MUTEX\textpipe AZUCARADORA\_0 & 76 \\
	
	llenadoras\_salida & mq	& MSG\_QUEUE\textpipe LLENADORA\_0 & 224 \\
	tapadora\_salida & mq	& MSG\_QUEUE\textpipe TAPADORA & 200 \\
	etiquetadora\_salida & mq 	& MSG\_QUEUE\textpipe ETIQUETADORA & 201 \\
	transportadoraA\_salida & mq	& MSG\_QUEUE\textpipe TRANSPORTADORA\_A & 202 \\
	repositor\_salida & mq	& MSG\_QUEUE\textpipe REPOSITOR & 203 \\
\end{tabular}
\caption{Objetos IPC del ejercicio 3.1.a}
\end{table}

\newpage
\subsection{Ejercicio 3.1.b}
La diferencia con el ejercicio anterior es la utilización de una cola de mensajes para sincronizar el llenado.

\subsubsection{Procesos}
\begin{itemize}
	\item \emph{transportadora\_A}, \emph{tapadora}, \emph{etiquetadora}, \emph{repositor}: Siguen funcionando igual que antes.
	\item \emph{llenadora}, \emph{azucardora}: Funcionan de manera similar que en el ejercicio anterior, pero utilizan un token que viaja por el canal de sincronización (la misma cola de mensajes para todas las llenadoras y azucaradoras) para decidir cual de los procesos despierta al otro.
\end{itemize}

\subsubsection{Mensajes y memorias compartidas}
El unico mensaje agregado es el necesario para la sincronización, \emph{sToken}, cada par \emph{azucaradora} y \emph{llenadora} corresponden a una boca de llenado, y se utiliza el número de boca (iniciado en 0) más 1 para identificar a que conjunto pertenece cada token en el canal de sincronización.
\begin{lstlisting}
	typedef struct {
		long tipo;
		size_t esperando;
	} sToken;
\end{lstlisting}

\subsubsection{Objetos IPC}
Se utlizan los mismo objetos IPC con la salvedad de que se elimina el semáforo \emph{mutex\_sync} y la memoria compartida \emph{sync}, y se agrega la cola de mensajes \emph{canal\_sync}, solo se mostrara la entrada de la cola de mensajes.

\begin{table}[ht!]
\centering
\begin{tabular}{l|l|l@{=}r}
	\emph{Nombre} & \emph{Tipo} & \emph{Discriminante} & \emph{Val.} \\
	\hline
	\multicolumn{4}{c}{ Idem anterior - \{ \emph{mutex\_sync}, \emph{sync} \} } \\
	\hline
	canal\_sync	& mq 	& MSG\_QUEUE\textpipe SYNC & 198 \\
	\hline
\end{tabular}
\caption{Objetos IPC del ejercicio 3.1.a}
\end{table}

\subsection{Ejercicio 3.2}
El ejercicio anterior ya esta preparado para extender al uso del repositor para suministrar el azucar a los procesos \emph{azucaradora}. Solo es necesario portar el mecanimos utilizado en los otros a dicho proceso, el cual consiste en en cuanto no quedan recurso enviar un mensaje \emph{sReposicion} al proceso \emph{repositor} y esperar el envio de un pack de recursos. El resto de la solución es identico y no se detallara.\footnote{Resulta util utilizar un comando similar al \emph{diff} para ver las diferencias entre cada ejercicio, especialemente el 3.}

\newpage
\subsection{Ejercicio 4.1}
El problema puede ser visto como un productor-consumidor, donde hay personas que se comportan como clientes y pueden tanto producir como consumir reservas y por otro lado otras que actuan como invitados que solo pueden consumir reservas. Debido a que una persona requiere dos condiciones para poder entrar y usar el gimnasio, una que haya lugar y la otra es tener reserva, tambien podria tratarse como una instancia de los filosofos comensales, o la competencia de un grupo de prcoesos por una familia de recursos comunes (en este caso dos, lugares y reservas). Yo he optado por la primera opción, donde no es necesario tener reserva para ingresar al gimnasio.

\subsection{Ejercicio 4.2}
La solución es muy similar al ejercicio 1.3, pero se ha optado por construir una clase \emph{monitor\_reservas} encargada de la sincronización en el acceso a la matriz de las reservas.

A los fines practicos se ha optado por definir la cantidad de días con la constante \emph{MAX\_DIAS = 7} (lo que puede traducirse como reservas semanales) y \emph{MAX\_CLIENTES = 20}, para poder tener una salida por pantalla más entendible.

\subsubsection{Procesos}
El unico cambio iportante en los procesos se encuentra en \emph{persona} en la forma que se implementa su comportamiento una vez ingreso al gimnasio, el cual puede ser simplificado como:
\begin{itemize}
	\item Intentar usar una reserva.
	\item En caso de tener reserva entrenar (dormir un tiempo).
	\item Si es un cliente puede o no realizar una reserva para el mismo día o otro.
\end{itemize}

El resto del ejercicio y los procesos son casi identicos al ejercicio 1.3.

\subsubsection{Mensajes y memorias compartidas}
El clase \emph{monitor\_reservas\_base} define toda la logica de como acceder a la matriz y operar con ella sin considerar que memoria compartida y semáforo se utiliza, es condición que el parametro \emph{M} sea compatible con una \emph{shm$<$sReservas$>$}. La definición de la matriz de reservas es las siguiente:

\begin{lstlisting}
	#define MAX_CLIENTES 20
	#define MAX_DIAS 7

	typedef struct {
		size_t registro[MAX_DIAS][MAX_CLIENTES];
	} sReservas;
\end{lstlisting}

Además como su nombre lo indica \emph{monitor\_reservas\_base} garantiza la exclusión mutua entre todos los procesos que acceden a la matriz.

\newpage
\subsubsection{Objetos IPC}
Solo se agregan el semáforo y la memoria compartida manejada por el monitor de reservas.
\begin{table}[ht!]
\centering
\begin{tabular}{l|l|c}
	\emph{Nombre} & \emph{Tipo} & \emph{Disc.} \\
	\hline
	mutex\_gim	& sem(0)	& 10 \\ 
	gim		& shm$<$sGimnasio$>$ & 11 \\
	cola1	& mq		& 16 \\
	cola2	& mq		& 17 \\
	\hline \hline
	\multicolumn{3}{c}{Monitor de Reservas} \\
	\hline
	reservas.mutex & sem(0)	& 12 \\
	reservas.reservas & shm$<$sReservas$>$ & 13 \\
\end{tabular}
\caption{Objetos IPC del ejercicio 4.2}
\end{table}

\subsection{Ejercicio 5}
Se extiende la solución del ejercicio anterior agregando un proceso para presentar los datos de estado por la pantalla gigante, un recepcionista a cargo de asigar entrenadores a los clientes, y un entrenador a cargo de asignar rutinas a los clientes.

\subsubsection{Procesos}
\begin{itemize}
	\item \emph{arribos} y \emph{puerta}: Identicos al ejercicio anterior.
	\item \emph{persona}: La comprobación y uso de la reserva es igual que el ejercicio anterior, lo que varia es la forma de entrenar que en este caso requiere de comunicación con el \emph{recepcionista} y un \emph{entrenador}
	\item \emph{recepcionista}: Es el encargado de asignar a cada cliente un entrenador, o de negar la atención por falta de entrenadores.
	\item \emph{entrenador}: Un entrenador es una persona que atiende clientes, como tal ingresa al gimnasio y ocupa un lugar, la diferencia es que se comunica con los clientes para enviarle mensajes \emph{sRutina}.
	\item \emph{pantalla\_gigante}: Su unica función es mostrar la información de estado del gimnasio por pantalla.
	\item \emph{pantalla\_gigante\_timer}:	Cada cierto tiempo activa a \emph{pantalla\_gigante}.
\end{itemize}

\subsubsection{Mensajes y memorias compartidas}
El monitor de reservas es identico al ejercicio anterior.

Se agrega la clase \emph{monitor\_aparatos} que provee exclusión mutua en el acceso al conjunto de aparatos. Entre las facilidades que provee esta el método \emph{for\_each\_aparato} que permite realizar una tarea sobre cada aparato, la unica condición es que la tarea implemente \emph{procesar\_aparato}. Esta facilidad se utiliza tanto para mostrar el estado como para buscar un aparato copatible con un cliente y una rutina.

La memoria compartida \emph{sAparatos} presenta un vector de aparatos en el atributo \emph{item} y una marca para el ultimo cambio, para que cada proceso sepa si existen cambios desde la ultima vez que lo modifico (debe guardarse el valor anterior del atributo).

\begin{lstlisting}
	typedef struct {
		sAparato item[MAX_APARATOS];
		size_t ultimo_cambio;
	} sAparatos;
\end{lstlisting}

El unico tipo de mensaje agregado es emitido por el entrenador para avisarle al cliente que rutina debe hacer. El campo \emph{tipo} y \emph{origen} se utilizan como en los mensajes anteriores. \emph{aparato} indica el identificador del aparato (que coincide con su posición en el vector \emph{sAparato.item} +1. \emph{id} indica el identificador de la rutina asignada. Y finalmente \emph{minutos} indica por cuanto tiempo deberia el cliente realizar la rutina.

\begin{lstlisting}
	typedef struct {
		long tipo;
		long origen;
		aparato_id aparato;
		enum eRutina id;
		size_t minutos;
	} sRutina;
\end{lstlisting}

Los procesos \emph{entrenador} usan las mismas facilidades para entrar/salir del gimnasio que los \emph{persona}, pero hay un proceso separado \emph{recepcionista} encargado de asignarle a cada cliente un entrenador disponible. La comunicación entre \emph{persona}, \emph{entrenador} y \emph{recepcionista} se lleva a cabo a travez de \emph{colaAtencion}, donde:
\begin{itemize}
	\item Un \emph{entrenador} al ingresar se registra con el \emph{recepcionista} para poder recibir clientes.
	\item Un cliente al ingresar se presenta en el mostrar y espera que el \emph{recepcionista} le asigne un \emph{entrenador}.
	\item Una vez asignado o cada vez que termina una rutina, el cliente le avisa al entrenador que esta disponible.
	\item Cada vez que un \emph{entrenador} recibe un pedido de un cliente este comprueba que pueda reservar un aparato, y que el cliente no deba retirarse. En caso satisfactorio el \emph{entrenador} envia una rutina cuyo identificador no es \emph{SALIR}.
	\item El cliente sigue entrenando hasta que su \emph{entrenador} le informa que debe irse.
\end{itemize}

\newpage
\subsubsection{Objetos IPC}
\begin{table}[ht!]
\centering
\begin{tabular}{l|l|c}
	\emph{Nombre} & \emph{Tipo} & \emph{Disc.} \\
	\hline
	lugares.mutex	& sem(0)	& 10 \\
	lugares.value	& shm$<$sBoundedValue$>$	& 11 \\
	cola1	& mq		& 16 \\
	cola2	& mq		& 17 \\
	\hline
	colaRecepcion	& mq	& 18 \\
	colaAtencion	& mq	& 19 \\
	entrenadores\_disponibles.mutex	& sem(0)	& 20 \\
	entrenadores\_disponibles.value	& shm$<$sBoundedValue$>$	& 21 \\
	pantalla\_gigante\_mostrar	& sem(0)	& 25 \\
	pantalla\_gigante\_aviso.mutex	& sem(0)	& 26 \\
	pantalla\_gigante\_aviso.value	& shm$<$sBoundedValue$>$	& 27 \\
	control\_ingreso	& sem(0)	& 30 \\
	\hline \hline
	\multicolumn{3}{c}{Monitor de Reservas} \\
	\hline
	reservas.mutex & sem(0)	& 12 \\
	reservas.reservas & shm$<$sReservas$>$ & 13 \\
	\hline \hline
	\multicolumn{3}{c}{Monitor de Aparatos} \\
	\hline
	aparatos.mutex	& sem(0)	& 14 \\
	aparatos.aparatos	& shm$<$sAparatos$>$	& 15 \\	
\end{tabular}
\caption{Objetos IPC del ejercicio 4.2}
\end{table}

\end{document}

